import logging
import os
import sys
import uuid

from fastapi import UploadFile, HTTPException
from pydantic import BaseModel
from starlette import status

from app.core.config import settings

logger=logging.getLogger(__name__)


# settings.FILE_DOWNLOAD_PATH

class FilePathInfo(BaseModel):
    #例如文件名为：Z:/uploads/1/test.txt
    #上传文件存储目录为 Z:/uploads
    root_path: str  #根目录  Z:/uploads
    sub_path: str  #存档目录 1/test.txt
    full_path: str #详细目录 Z:/uploads/1/test.txt

def format_file_name_to_read(sub_path:str) -> str:
    full_name=f'{settings.FILE_DOWNLOAD_PATH}/{sub_path}'
    return full_name
def format_file_name_to_save(kb_id, file_name:str) -> FilePathInfo:
    """
    格式化文件名
    """
    if not os.path.exists(settings.FILE_DOWNLOAD_PATH):
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="文件下载路径[%s]不存在" % settings.FILE_DOWNLOAD_PATH,
        )
    tmp_dir='%s/%d' % (settings.FILE_DOWNLOAD_PATH, kb_id)
    if not os.path.exists(tmp_dir):
        os.makedirs(tmp_dir)
    _, file_extension=os.path.splitext(file_name)
    # file_extension=file_extension.lstrip('.')
    logger.debug("file_name:%s,file_extension:%s,_:%s" % (file_name,file_extension,_))
    sub_path=f'{kb_id}/{uuid.uuid4().hex}{file_extension}'
    full_name=f'{settings.FILE_DOWNLOAD_PATH}/{sub_path}'
    logger.info("full_name:%s" % (full_name))
    return FilePathInfo(
        root_path=settings.FILE_DOWNLOAD_PATH,
        sub_path=sub_path,
        full_path=full_name,
    )  # 返回生成的文件路径

MAX_FILE_SIZE = 1024 * 1024 * 10 #限制文件 10MB,因为文件太大会导致向量耗时太久
async def asave_kb_file(
        kb_id:int,
        file:UploadFile,
        file_desc:str=None,
        file_content:bytes=None,#因为在上传文件时，file.read()已经读取了文件内容，所以这里就不需要再读取了
) -> FilePathInfo:
    """
    保存知识库文件
    """
    logger.debug("准备保存文件 save_kb_file:kb_id:%d,file_name:%s,file_desc:%s" % (kb_id,file.filename,file_desc))
    file_path_info:FilePathInfo=format_file_name_to_save(kb_id, file.filename)
    content = file_content
    logger.debug("文件大小:%d" % (len(content)))
    if len(content) > MAX_FILE_SIZE:
        raise HTTPException(status_code=500, detail="文件大小超过限制（10MB）")
    with open(file_path_info.full_path, 'wb') as f:
        f.write(content)
    logger.info("文件保存成功 save_kb_file:kb_id:%d,file_name:%s,file_desc:%s,file_path:%s" % (kb_id,file.filename,file_desc,file_path_info.full_path))
    return file_path_info

async def delete_kb_file(
        sub_path:str
) -> None:
    """
    删除知识库文件
    """
    file_path='%s/%s' % (settings.FILE_DOWNLOAD_PATH, sub_path)
    logger.debug("准备删除文件 delete_kb_file  file_path:%s" % (file_path))
    if os.path.exists(file_path):
        os.remove(file_path)
    logger.info("文件删除成功 delete_kb_file  file_path:%s" % (file_path))

if __name__ == '__main__':
    from app.core.config import settings

    logger.setLevel(logging.NOTSET)
    logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s %(levelname)-5.5s [%(name)s(%(lineno)d)] %(message)s',
                    datefmt='%a, %d %b %Y %H:%M:%S',
                        handlers=[logging.StreamHandler(stream=sys.stdout)],
                    )
    logger.debug('asus')
    # FILE_DOWNLOAD_PATH:str = os.getenv("FILE_DOWNLOAD_PATH", "uploads")
    # print('FILE_DOWNLOAD_PATH:',FILE_DOWNLOAD_PATH)
    #
    # FILE_DOWNLOAD_PATH: str = settings.FILE_DOWNLOAD_PATH
    # print('FILE_DOWNLOAD_PATH:', FILE_DOWNLOAD_PATH)
    format_file_name_to_save(1, 'Z:/uploads/test.txt.abc')
    format_file_name_to_save(1, 'Z:/uploads/testtxtabc')
    format_file_name_to_save(1, 'Z:/uploads/abc.txt')
